home *** CD-ROM | disk | FTP | other *** search
- /* Difference utility for Eclectus integration utilities.
- Copyright (C) 1992-1996 Eclectus (D. John Anderson, Alan B. Harper).
-
- This file is part of the Eclectus integration utilities.
-
- Eclectus integration utilities are free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 1, or
- (at your option) any later version.
-
- Eclectus integration utilities is distributed in the hope that it
- will be useful, but WITHOUT ANY WARRANTY; without even the implied
- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with the Eclectus integration utilities; see the file COPYING.
- If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge,
- MA 02139, USA. */
-
- #include "diff.h"
- #include <stdlib.h>
- #include <string.h>
-
- static int diffPathDepth;
- static int exitStatus = EXIT_SUCCESS;
- static int ignoreBinaryFiles;
- static int returnEXIT_SUCCESS;
- static unsigned int hashValue;
- static const char *programNamePtr;
-
- void CommandLine (int argc,
- const char **argv,
- const char **pathOldNamePtrPtr,
- const char **pathNewNamePtrPtr);
- void CommandLineError (int errorMessage, const char *theString);
- void DiffPaths (const char *pathOldNamePtr, const char *pathNewNamePtr);
- void PrintPathSuffix (char commandChar, const char *pathPtr);
- int __cdecl main (int argc, const char **argv);
-
- void
- CommandLine (int argc, const char **argv, const char **pathOldNamePtrPtr, const char **pathNewNamePtrPtr)
- /*
- * Parses the command line.
- */
- {
- char commandChar;
- register const char *commandStringPtr;
- int fileCount;
-
- fileCount = 0;
-
- programNamePtr = *argv++;
- argc--;
-
- /* Parse the commands and make sure they are legal */
-
- while (argc > 0) {
- commandStringPtr = *argv++;
- argc--;
- if (*commandStringPtr != '-') {
- if (fileCount >= 2)
- CommandLineError (TWO_FILES_ONLY, NULL);
- if (FileType (commandStringPtr) == BAD_FILE_TYPE)
- ErrorWithStringArgument (CANT_OPEN_FILE, commandStringPtr);
-
- if (fileCount == 0)
- *pathOldNamePtrPtr = commandStringPtr;
- else
- *pathNewNamePtrPtr = commandStringPtr;
-
- fileCount ++;
- } else {
- if (strlen (commandStringPtr) != 2)
- CommandLineError (UNEXPECTED_OPTION, commandStringPtr);
- commandChar = *(commandStringPtr + 1);
- switch (commandChar) {
- case ('i'):
- ignoreBinaryFiles = TRUE;
- break;
- case ('y'):
- returnEXIT_SUCCESS = TRUE;
- break;
- #ifdef DF_DEBUG
- case ('X'):
- ECCheckFreedBlocks = 1;
- break;
- case ('x'):
- ECHeapCheckOn = 1;
- break;
- #endif
- default:
- CommandLineError (UNEXPECTED_OPTION, commandStringPtr);
- break;
- }
- }
- }
- if (fileCount != 2)
- CommandLineError (TWO_FILES_ONLY, NULL);
- }
-
- void
- CommandLineError (int errorMessage, const char *theString)
- /*
- * Part of CommandLine.
- */
- {
- fprintf (stderr, "# - ");
- if (theString != NULL)
- fprintf (stderr, ECMessagessArray [errorMessage], theString);
- else
- fprintf (stderr, ECMessagessArray [errorMessage], "");
- fprintf (stderr, ".\n\n"
- "### Difference version %s\n"
- "#usage: %s SourcePath ModifiedPath > DifferenceScriptFile\n"
- "# -y Always return EXIT_SUCCESS\n"
- "# -i ignore binary files\n\n",
- VERSION_STRING,
- programNamePtr);
- exit (EXIT_FAILURE);
- }
-
- void
- DiffPaths (const char *pathOldNamePtr, const char *pathNewNamePtr)
- {
- register unsigned char *charPtr;
- register int count;
- char differenceChar;
- int fileKind;
- fileNameListPType fileNameListPtr;
- int filesAreIdentical;
- register unsigned char hexDigit;
- char *nameSuffixPtr;
- struct file_data newFile;
- int nonASCIIChars;
- struct file_data oldFile;
- char pathNewName [FILENAME_MAX + 1];
- int pathNewPrefixLength;
- char pathOldName [FILENAME_MAX + 1];
- int pathOldPrefixLength;
- int suffixLengthPlusOne;
- register unsigned char theChar;
- register int totalBytes;
-
- diffPathDepth++;
- fileKind = FileType (pathNewNamePtr);
- switch (fileKind) {
- case (DIRECTORY_TYPE):
- PrintPathSuffix ('d', pathNewNamePtr);
- fileNameListPtr = ReadDirectory (pathNewNamePtr);
- if (fileNameListPtr == NULL)
- Error (UNEXPECTED_IO_ERROR);
- nameSuffixPtr = fileNameListPtr->names;
-
- pathNewPrefixLength = strlen (pathNewNamePtr);
- (void) memcpy (pathNewName, pathNewNamePtr, pathNewPrefixLength);
- if (pathNewName [pathNewPrefixLength-1] != DIRECTORY_CHAR) {
- pathNewName [pathNewPrefixLength] = DIRECTORY_CHAR;
- pathNewPrefixLength ++;
- }
- pathOldPrefixLength = strlen (pathOldNamePtr);
- (void) memcpy (pathOldName, pathOldNamePtr, pathOldPrefixLength);
- if (pathOldName [pathOldPrefixLength-1] != DIRECTORY_CHAR) {
- pathOldName [pathOldPrefixLength] = DIRECTORY_CHAR;
- pathOldPrefixLength ++;
- }
-
- while (*nameSuffixPtr != '\0') {
- suffixLengthPlusOne = strlen (nameSuffixPtr) + 1;
- if (pathNewPrefixLength + suffixLengthPlusOne > FILENAME_MAX) {
- fprintf (stderr, "%s%s\n", pathNewNamePtr, nameSuffixPtr);
- Error (PATH_TOO_LONG);
- }
- if (pathOldPrefixLength + suffixLengthPlusOne > FILENAME_MAX) {
- fprintf (stderr, "%s%s\n", pathOldNamePtr, nameSuffixPtr);
- Error (PATH_TOO_LONG);
- }
- if (!IgnoreFile (nameSuffixPtr)) {
- (void) memcpy (pathNewName + pathNewPrefixLength, nameSuffixPtr, suffixLengthPlusOne);
- (void) memcpy (pathOldName + pathOldPrefixLength, nameSuffixPtr, suffixLengthPlusOne);
- DiffPaths (pathOldName, pathNewName);
- }
- nameSuffixPtr += suffixLengthPlusOne;
- }
- free (fileNameListPtr);
- printf ("u\n");
- break;
- case (BINARY_TYPE):
- if (!ignoreBinaryFiles) {
- PrintPathSuffix ('b', pathNewNamePtr);
- bzero (&newFile, sizeof (struct file_data));
- bzero (&oldFile, sizeof (struct file_data));
- newFile.namePtr = pathNewNamePtr;
- newFile.desc = fopen (pathNewNamePtr, "rb");
- if (newFile.desc == NULL)
- ErrorWithStringArgument (CANT_OPEN_FILE, pathNewNamePtr);
- oldFile.namePtr = pathOldNamePtr;
- oldFile.desc = fopen (pathOldNamePtr, "rb");
- slurp (&newFile);
- slurp (&oldFile);
- totalBytes = newFile.buffered_chars;
- if (newFile.missing_newline)
- totalBytes --;
- filesAreIdentical = FALSE;
- if (newFile.buffered_chars == oldFile.buffered_chars &&
- newFile.missing_newline == oldFile.missing_newline)
- filesAreIdentical = memcmp (newFile.buffer, oldFile.buffer, totalBytes) == 0;
- charPtr = (unsigned char *) newFile.buffer;
- if (filesAreIdentical) {
- differenceChar = ' ';
- count = totalBytes;
- while (count-- > 0)
- hashValue = HASH (hashValue, *charPtr++);
- } else {
- differenceChar = '*';
- exitStatus = EXIT_FAILURE;
- printf ("H%d\n", (totalBytes + (HEX_LINE_LENGTH -1)) / HEX_LINE_LENGTH);
- count = 0;
- while (count < totalBytes) {
- theChar = *charPtr++;
- hashValue = HASH (hashValue, theChar);
- hexDigit = (theChar >> 4) & 0X0F;
- if (hexDigit < 10)
- hexDigit += '0';
- else
- hexDigit += 'A' - 10;
- putchar (hexDigit);
- hexDigit = theChar & 0X0F;
- if (hexDigit <= 9)
- hexDigit += '0';
- else
- hexDigit += 'A' - 10;
- putchar (hexDigit);
- count ++;
- if (count % HEX_LINE_LENGTH == 0)
- putchar ('\n');
- }
- if (count % HEX_LINE_LENGTH != 0)
- putchar ('\n');
- }
- printf ("h%d\n", hashValue);
- hashValue = 0;
- fprintf (stderr, " BINARY FILE %c%s\n", differenceChar, pathNewNamePtr);
- freeFile (&oldFile);
- freeFile (&newFile);
- }
- break;
- case (TEXT_TYPE):
- PrintPathSuffix ('f', pathNewNamePtr);
- bzero (&newFile, sizeof (struct file_data));
- bzero (&oldFile, sizeof (struct file_data));
- newFile.namePtr = pathNewNamePtr;
- newFile.desc = fopen (pathNewNamePtr, "r");
- if (newFile.desc == NULL)
- ErrorWithStringArgument (CANT_OPEN_FILE, pathNewNamePtr);
- oldFile.namePtr = pathOldNamePtr;
- oldFile.desc = fopen (pathOldNamePtr, "r");
-
- diff_2_files (&oldFile, &newFile);
- differenceChar = ' ';
- filesAreIdentical = newFile.scriptPtr == NULL && (oldFile.buffered_lines == newFile.buffered_lines);
- if (!filesAreIdentical) {
- differenceChar = '*';
- exitStatus = EXIT_FAILURE;
- }
- print_rcs_script (&oldFile, &newFile);
- /*
- * Print the hash for newFile. We use a known value for '\n' since it varies between machines.
- */
- charPtr = (unsigned char *) newFile.buffer;
- count = newFile.buffered_chars;
- if (newFile.missing_newline)
- count --;
- nonASCIIChars = 0;
- while (count > 0) {
- theChar = *charPtr++;
- if (theChar == '\n')
- theChar = 13;
- hashValue = HASH (hashValue, theChar);
- if ((unsigned char) theChar > 127)
- nonASCIIChars++;
- count --;
- }
- printf ("h%d\n", hashValue);
- hashValue = 0;
- if (nonASCIIChars == 0)
- fprintf (stderr, " ");
- else
- fprintf (stderr, "%6d NON-ASCII CHARACTERS ", nonASCIIChars);
- fprintf (stderr, "%c%s\n", differenceChar, pathNewNamePtr);
- freeFile (&oldFile);
- freeFile (&newFile);
- break;
- }
- diffPathDepth--;
- }
-
- void
- PrintPathSuffix (char commandChar, const char *pathPtr)
- /*
- * Prints the command character appended by the suffix of pathPtr.
- */
- {
- const char *suffixPtr;
-
- if (diffPathDepth > 1) {
- suffixPtr = strrchr (pathPtr, DIRECTORY_CHAR);
- if (suffixPtr != NULL)
- suffixPtr ++;
- else
- suffixPtr = pathPtr;
- printf ("%c%s\n", commandChar, suffixPtr);
- }
- }
-
- int
- __cdecl main (int argc, const char **argv)
- {
- #ifdef DF_DEBUG
- ECUns32 allocatedBytes;
- #endif
- const char *pathOldNamePtr;
- const char *pathNewNamePtr;
-
- hashValue = 0;
- CommandLine (argc, argv, &pathOldNamePtr, &pathNewNamePtr);
- printf ("%s# Version %s\n# Difference %s %s\n",
- DIFFERENCE_SCRIPT_START_STRING,
- VERSION_STRING,
- pathOldNamePtr,
- pathNewNamePtr);
- DiffPaths (pathOldNamePtr, pathNewNamePtr);
- printf ("h%d\n", hashValue);
- hashValue = 0;
-
- #ifdef DF_DEBUG
- allocatedBytes = ECDebugPrintMemoryUsage (stderr);
- if (allocatedBytes != 0) {
- fprintf (stderr, "\n\n"
- "MEMORY LEAK! MEMORY LEAK! MEMORY LEAK! MEMORY LEAK!\n"
- "MEMORY LEAK! MEMORY LEAK! MEMORY LEAK! MEMORY LEAK!\n"
- "MEMORY LEAK! MEMORY LEAK! MEMORY LEAK! MEMORY LEAK!\n"
- "MEMORY LEAK! MEMORY LEAK! MEMORY LEAK! MEMORY LEAK!\n"
- "MEMORY LEAK! MEMORY LEAK! MEMORY LEAK! MEMORY LEAK!\n"
- "\n\n");
- }
- #endif
- if (exitStatus == EXIT_SUCCESS)
- fprintf (stderr, "No difference between file(s).\n");
- else
- fprintf (stderr, "File(s) marked \"*\" differ.\n");
- if (returnEXIT_SUCCESS)
- exitStatus = EXIT_SUCCESS;
- return (exitStatus);
- }
-
-